/*
 * main.cpp for gen_3d_paths
 *
 *  Created on: Apr 4, 2012
 *      Author: hxu
 */
//#pragma  warning(disable:4996) // for VS2011
#include <iostream>
#include <ctime>
#include "Toolset.h"
#include "Btree3D.h"

#define OS_TYPE '\\' // for windows

using namespace std;

void help_info();
fstream fileout;

int main(int argc, const char* argv[]) {

	string setupname = "", ifname = ""; // setup file and circuit file
	string ofname, logname;
	string prompt;
	size_t pos1, pos2;
	time_t tstart, tend, date;
	double cputime = 0;
	string OUTDIR = ".";
	string prog_name = argv[0];
	prog_name = prog_name.substr(prog_name.rfind("/") + 1, prog_name.size());

	/* determine file name */
	cout << endl << " *** " << prog_name << " ******************* " << endl;
	cout << " ------------------------------------------ " << endl;

	// read in paramters
	if (argc >= 5) {
		for (int i = 1; i <= argc - 1; i++) {
			if (argv[i][0] == '-') {
				// an option
				switch (argv[i][1]) {
				case 's':
					setupname = argv[++i];
					break;
				case 'i':
					ifname = argv[++i];
					break;
				case 'o':
					ofname = argv[++i];
					break;
				case 'd':
					OUTDIR = argv[++i];
					break;
				}
			} else
				i++; // skip the option
		}
	}

	try {
		/* read in setup and input file */
		ifstream setupstream(setupname.c_str(), ios::in);
		ifstream ifile(ifname.c_str(), ios::in);
		if (!setupstream) {
			string errstr = " Error: No setup file \"" + setupname + "\"!";
			help_info();
			throw(errstr.c_str());
		} else {
			cout << " * Reading setup file: " << setupname << endl;
		}

		if (!ifile) {
			string errstr = " Error: No topology file \"" + ifname + "\"!";
			help_info();
			throw(errstr.c_str());
		} else {
			cout << " * Reading topology file: " << ifname << endl;
		}

		/* define output and log files */

		if (ofname == "") {
			ofname = ifname;
			pos1 = ofname.rfind("."); // replace the attrbute name
			pos2 = ofname.rfind(OS_TYPE, pos1);
			ofname.replace(pos1, ofname.size(), ".skitter");

			// add a directory symbol
			char tstr = *(--OUTDIR.end());
			if (tstr != OS_TYPE)
				OUTDIR = OUTDIR + OS_TYPE;

			// add the directory name
			if (pos2 != string::npos) {
				// "/" is found
				ofname.replace(0, pos2 + 1, OUTDIR);
			} else
				ofname.insert(0, OUTDIR);
		}
		logname = ofname;
		pos1 = logname.rfind(".skitter");
		logname.replace(pos1, logname.size(), ".log");

		// check whether the file exists
		fileout.open(ofname.c_str(), ios::in);
		if (!fileout)
			prompt = " * Write to \"" + ofname + "\".\n";
		else
			prompt = " * Overwrite \"" + ofname + "\".\n";
		fileout.close();

		// open to write
		fileout.open(ofname.c_str(), ios::out);
		if (fileout.fail()) {
			string errstr = " Cannot write to " + ofname + "!";
			throw(errstr.c_str());
		}
		// output
		date = time(NULL);
		fileout << "# Generated by " << argv[0] << "." << endl;
		fileout << "# Date: " << ctime(&date) << endl << endl;

		/* Model */
		tstart = clock();
		cout << prompt;
		Cxuh::Btree3D tree(setupstream, ifile);
		//fileout << tree;

		// parse

		tend = clock();
		cputime = (tend - tstart) / double(CLOCKS_PER_SEC);
		fileout << endl << "# CPU time: " << cputime << " s." << endl << endl;

		ifile.close();
		setupstream.close();
		fileout.close();
	} catch (const char *a) {
		string err(a);
		cerr << err << endl << endl;
		return -1;
	} catch (exception& e) {
		cerr << e.what();
		return -1;
	}

	cout << " * Successfully executed! Enter any key to continue..." << endl << endl;

	std::getchar();

	return 0;

}

void help_info() {
	cout << "  Help" << endl;
	cout << "  -s setup_file    # Includes process and voltage info." << endl;
	cout << "  -i input_file    # Includes 3D tree topology info." << endl;
	cout
			<< "  -d [output_directory]    # Stored in current directory by default."
			<< endl;
	cout
			<< "  -o [output_file]   # Output file, in the same name as the input_file by default"
			<< endl << endl;
}

